
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class TreeUtil
{

    /**
     * 横向步长
     */

    private int stepX = 100;

    /**
     * 纵向步长
     */

    private int stepY = 100;

    /**
     * 叶子节点
     */
    private List<TreeNode> leafNodesList = new ArrayList<TreeNode>();

    private int halfNodeSum;
    private int startY = 0;
    private int startX = 0;

    private HashMap<String, HashMap<String, Integer>> result = new HashMap<String, HashMap<String, Integer>>();

    public TreeUtil()
    {

    }

    public TreeNode CreateTreeNode(String id, int deep, TreeNode pTreeNode,
            Integer type)
    {
        TreeNode treeNode = new TreeNode();
        treeNode.setId(id);
        treeNode.setDeep(deep);
        treeNode.setY(deep * stepY);
        treeNode.setParent(pTreeNode);
        treeNode.setType(type);
        return treeNode;
    }

    public void draw(TreeNode root)
    {

        for (int i = 0; i < root.children.size(); i++)
        {
            draw(root.children.get(i));
        }
        int x = GetCoordinateY(root);
        root.setX(x);
        HashMap<String, Integer> offset = new HashMap<>();
        offset.put("x", root.getX());
        offset.put("y", root.getY());
        result.put(root.getId(), offset);
        StringBuilder sb = new StringBuilder();
        sb.append("var node = new JTopo.Node('" + root.getId() + "');");
        sb.append("node.setLocation(" + root.getX() + "," + root.getY() + ");");
        sb.append("scene.add(node);");
        System.out.println(sb);

    }

    private int GetCoordinateY(TreeNode root)
    {
        int coordinateY = 0;
        if (root.children.size() > 1)
        {
            coordinateY = (root.children.get(0).getX()
                    + root.children.get(root.children.size() - 1).getX()) / 2;
        }
        else
            if (root.children.size() == 1)
            {
                coordinateY = root.children.get(0).getX();
            }
            else
            {
                coordinateY = GetLeafCoordinate(root.getId());
            }

        return coordinateY;
    }

    private int GetLeafCoordinate(String id)
    {
        int coordinate = 0;
        for (int i = 0; i < leafNodesList.size(); i++)
        {
            if (!leafNodesList.get(i).getId().equals(id))
                continue;
            if (i <= halfNodeSum)
            {
                coordinate = startX - stepX * (halfNodeSum - i);
            }
            else
            {
                coordinate = startX + stepX * (i - halfNodeSum);
            }
            break;
        }

        return coordinate;
    }

    public static void main(String[] args)
    {

        TreeUtil tu = new TreeUtil();
        tu.setStepY(100);
        tu.setStepX(100);
        // id 和 自己的treenode
        HashMap<String, TreeNode> idNode = new HashMap<String, TreeNode>();
        // 根节点
        TreeNode root = tu.CreateTreeNode("根节点", 0, null, 20);// type = 10

        idNode.put("根节点", root);

        // 二层节点
        for (int j = 0; j < 5; j++) // 五个下级
        {
            TreeNode fwroot = idNode.get("根节点"); // 父节点是fw
            TreeNode secondNode = tu.CreateTreeNode("二层节点" + j, 1, fwroot, 21);// type=20

            if (fwroot == null)
            { // 父id不存在时候跳过这个
                continue;
            }
            fwroot.getChildren().add(secondNode);// 父节点的孩子集合加入这个节点
            idNode.put("二层节点" + j, secondNode);

            // 三层节点
            for (int i = 0; i < 2; i++)
            {
                // 父节点是 secondNode
                TreeNode thirdNode = tu.CreateTreeNode("三层节点" + j + "-" + i, 2,
                        secondNode, 30); // type=30
                if (secondNode == null)
                { // 父id不存在时候跳过这个
                    continue;
                }
                secondNode.getChildren().add(thirdNode);// 父节点的孩子集合加入这个节点
                idNode.put("三层节点" + j + "-" + i, thirdNode);
            }
        }
        // 找到叶子节点序
        ArrayList<String> leafIndex = new ArrayList<String>();
        findLeaf(root, leafIndex);
        for (int i = 0; i < leafIndex.size(); i++)
        {
            tu.getLeafNodesList().add(idNode.get(leafIndex.get(i)));
        }
        // System.out.println(leafIndex);
        tu.draw(root);

        System.out.println(tu.getResult());
    }

    public static void findLeaf(TreeNode root, ArrayList<String> leafIndex)
    {
        List<TreeNode> children = root.getChildren();
        if (children.size() > 0)
        {
            for (int i = 0; i < children.size(); i++)
            {
                findLeaf(children.get(i), leafIndex);
            }
        }
        else
        {
            leafIndex.add(root.getId());
        }
    }

    public int getStepX()
    {
        return stepX;
    }

    public void setStepX(int stepX)
    {
        this.stepX = stepX;
    }

    public int getStepY()
    {
        return stepY;
    }

    public void setStepY(int stepY)
    {
        this.stepY = stepY;
    }

    public List<TreeNode> getLeafNodesList()
    {
        return leafNodesList;
    }

    public void setLeafNodesList(List<TreeNode> leafNodesList)
    {
        this.leafNodesList = leafNodesList;
    }

    public int getHalfNodeSum()
    {
        return halfNodeSum;
    }

    public void setHalfNodeSum(int halfNodeSum)
    {
        this.halfNodeSum = halfNodeSum;
    }

    public int getStartY()
    {
        return startY;
    }

    public void setStartY(int startY)
    {
        this.startY = startY;
    }

    public int getStartX()
    {
        return startX;
    }

    public void setStartX(int startX)
    {
        this.startX = startX;
    }

    public HashMap<String, HashMap<String, Integer>> getResult()
    {
        return result;
    }

    public void setResult(HashMap<String, HashMap<String, Integer>> result)
    {
        this.result = result;
    }

}
